/*
 * tr_definitions.h: Main header file for Transport Layer
 * */

#ifndef TR_DEFINITIONS_H
#define TR_DEFINITIONS_H

#include <cnet.h>
#include <cnetsupport.h>
#include <limits.h>
#include "../global/g_definitions.h"

#define TR_WINDOW_SIZE 2	// number of packets in transport window
#define SEQ_MAX USHRT_MAX	// largest sequence number supported

#define TR_ACK_TIMER EV_TIMER3	// timer for ACK timeout
//#define TR_ACK_TIMEOUT 9*10000000	// default ACK timeout
 #define TR_ACK_TIMEOUT 100*10000000        // default ACK timeout
#define TR_ACK_TIMEOUT_MAX 100*10000000	// maximum ACK timeout
#define TR_ACK_TIMEOUT_MIN 1*1000000	// minimum ACK timeout
#define TR_ACK_TIMEOUT_INC 10*10000	// ACK timeout adjustment increment
#define TR_ACK_TIMEOUT_PENALTY 10	// ACK timeout penalty factor

#define NOACKINFO 0		// identifier for no ACK
#define ACK true
#define NAK false

/*
 * MSG: Message from Application Layer
 */
typedef struct {
  char		data[MAX_MESSAGE_SIZE];
} MSG;

/*
 * PACKET: Transport Layer packet structure
 */
#pragma pack(push)		// store default alignment
#pragma pack(1)			// force byte alignment
typedef struct {
  unsigned char	src,		// packet source address
		dest;		// packet destination address
  uint16_t	seq,		// sequence number of packet
		seq_ack;	// sequence number of acknowledged packet
  unsigned char	ack;		// ACK/NAK status
  uint16_t	len,		// length of message data field
		crc_head,	// header checksum
		crc_msg;	// message checksum
  MSG		msg;		// message from Application Layer
} PACKET;
#pragma pack(pop)		// restore default alignment

#define PACKET_HEADER_SIZE	(sizeof(PACKET) - sizeof(MSG))
#define PACKET_SIZE(pkt)	(PACKET_HEADER_SIZE + pkt.len)
#define PACKET_SIZE_PTR(pkt)	(PACKET_HEADER_SIZE + pkt->len)

/*
 * PKT_ID: 32-bit packet identifier using address and sequence number
 */
typedef struct {
  CnetTimerID	tid;		// unique identifier of ACK timer
  bool		enabled;	//for timer disabling
  CnetAddr	addr;		// address of node packet is for
  uint16_t	seq;		// packet sequence number
} PACKET_ID;

/*
 * WINDOW: Transport window for remote node
 */
typedef struct {
  VECTOR	pkts,		// packets in window
		pkt_ids;	// packet identifiers for in flight packets
  uint16_t	next_seq,	// next sequence number in window
		size;		// current window size
  
} WINDOW;

/*
 * NODE: Data about another node on the network
 */
typedef struct {
  CnetAddr	addr;		// node address
  WINDOW*	window;		// node transport window
  VECTOR	acks;		// acknowledgment queue
  CnetTime	ack_timeout;	// timeout until retransmit
} NODE;

/*
 * ACK_PENDING: Acknowledgment waiting to be transmitted
 */
typedef struct {
  uint16_t	seq_ack;	// sequence number of acknowledgment
  bool		ack;		// ACK/NAK status
} ACK_PENDING;

#endif

